package sim;

import game.Constants;

import java.util.Random;


public class SocialDiversity {

	private static int HABITAT_DIVERSITY_EXP_DIST = 1;
	private static int HABITAT_DIVERSITY_POWER_DIST = 2;
	private static int HABITAT_DIVERSITY_GAUSS_DIST = 3;
	private static int GaussCenterCol = 100;
	private static int GaussCenterRow = 100;
	
	public static SocialDiversity DiversityFacotory = new SocialDiversity();

	private Random rand ;
	       
	/* Calculates distance between two points */
	int calculateHD(int i, int j, int p, int q)
	{
	return (int) Math.sqrt( (i-p)*(i-p)+(j-q)*(j-q) ) ;
	}
	
	/* Calculates potential value for individual environment point */
	double calculatePotentialValue(int i, int j)
	{
		double result, magnitude, spread;
		int norm;
		result = 1.0;
		
		norm = calculateHD(i, j, GaussCenterRow, GaussCenterCol);
		magnitude =  1.0;
		spread = 5000.0;
		result =  magnitude*Math.exp((-1.0*norm*norm)/spread);
		
		return result;
	}

	public static SocialDiversity getDiversityFacotory() {
		return DiversityFacotory;
	}

	private SocialDiversity() {
		rand = new Random(System.currentTimeMillis());
	
	}


	public double getNext(int i, int j){
		double X = rand.nextDouble();
		if(Constants.DIVERSITY_DISTR_TYPE == HABITAT_DIVERSITY_EXP_DIST)
			return exponentialDist(X);
		else if (Constants.DIVERSITY_DISTR_TYPE  == HABITAT_DIVERSITY_POWER_DIST)
			return powerLawDist(X);
		else if (Constants.DIVERSITY_DISTR_TYPE  == HABITAT_DIVERSITY_GAUSS_DIST)
			return calculatePotentialValue(i, j);
		return -1;
	}
	

	public double powerLawDist(double x) {
		return Constants.AVALUE * (1.0 / Math.sqrt(x) - 2);
	}

	public double exponentialDist(double x) {
		return Constants.AVALUE * (-Math.log(x) - 1);
	}
	

	public static void main(String[] args) {
		SocialDiversity sd= new SocialDiversity();
		
		for(int i=0;i<200;i++){
			
			for(int j=0;j<200;j++){
				System.out.print("\t"+ String.valueOf( sd.calculatePotentialValue(i, j)) );
			}
			System.out.println();
		}
	}

}
